﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace StudyCode.Delegate
{
    //[访问性] delegate [返回值] [委托类型名称] [参数-(类似方法的参数)]
    public delegate void CustomAction(string text);

    public delegate void GenericsAction<T>(T param);

    public partial class Form1 : Form
    {
        public CustomAction Action { get; set; }

        public GenericsAction<string> GAction { get; set; }

        //构造函数 [访问权限] [当前类名] ([参数列表])
        public Form1()
        {
            InitializeComponent();

            //预定事件
            Load += Form1_Load;

            Load += Form2_Load;

            Action = ShowMessage;

            //把泛型方法，的泛型具体化，定义为GAcition的类型
            GAction = ShowGenericsMessage;


        }

        private void Form2_Load(object sender, EventArgs e)
        {
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            MessageBox.Show("加载窗体");
        }

        //两个方法的方法名一样，但是参数列表不一样就叫重载
        //函数的参数列表有，参数个数，和每个参数类型
        private void ShowMessage(string text, string i)
        {
            MessageBox.Show(text);
        }

        private void ShowMessage(string str)
        {
            MessageBox.Show(str);
        }

        private void ShowGenericsMessage<T>(T param)
        {
            MessageBox.Show(param.ToString());
        }

        private void btnExcute_Click(object sender, EventArgs e)
        {
            var list = new List<string> { "string1", "string2", "string3" };

            Foreach(list, ShowMessage);

            //匿名委托 匿名委托的返回值是在方法体里面定义的
            //参数列表需要在声明的时候定义
            Foreach(list, delegate(string str, string text)
            {
                Debug.WriteLine(str);
                //定义返回值额
                //return '1';
            });
            //去掉大括号的if写法,if下一句如果是一句可以去掉大括号
            if (list.Count == 3)
                Debug.Write(3);

            //lambda表达式
            Foreach(list, (string item, string text) => { Debug.WriteLine(item); });

            //去掉大括号的原理同if
            Foreach(list, (item, text) => Debug.WriteLine(item));

            list.ForEach(item => Debug.Write(item));

            list.ForEach(ShowMessage);
        }

        public void Foreach(List<string> list, Action<string, string> action)
        {
            //if(list==null)
            //    throw new ArgumentNullException("list");
            foreach (string item in list)
            {
                action(item, item);
            }
        }

        private void btnCallBack_Click(object sender, EventArgs e)
        {
            var user = new User
            {
                Name = "天问",
                Age = 26,
                Gender = true,
            };

            user.ShowInfo(item => { Text = item; });

            //扩展方法
            // user.ShowInformation(item => MessageBox.Show(item));
        }
    }

    //扩展方法，定义到静态类的静态方法，并且第一个参数加this
    public static class Extensions
    {
        public static void ShowInformation(this User user, Action<string> showInfoAction)
        {
            var info = string.Format("{0}-{1}-{2}", user.Name, user.Age, user.Gender);

            showInfoAction(info);
        }
    }

    public class User
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public bool Gender { get; set; }

        public void ShowInfo(Action<string> showInfoAction)
        {
            var info = string.Format("{0}-{1}-{2}", Name, Age, Gender);

            showInfoAction(info);
        }

    }
}
